package org.jeecg.common.util;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

public class CamelCaseConverter {

    /**
     * 通用的驼峰命名转换方法
     * @param input 输入对象，可以是List或单体对象
     * @return 转换后的Map数据
     */
    public static List<Map<String, Object>> convertToCamelCaseMap(Object input) {
        List<Object> objects = toObjectList(input);
        return objects.stream()
                .map(CamelCaseConverter::convertObjectToMap)
                .collect(Collectors.toList());
    }

    /**
     * 将输入转换为对象列表
     */
    private static List<Object> toObjectList(Object input) {
        if (input instanceof List) {
            return (List<Object>) input;
        } else {
            return Collections.singletonList(input);
        }
    }

    /**
     * 将单个对象转换为Map，自动检测并转换字段命名风格
     */
    private static Map<String, Object> convertObjectToMap(Object obj) {
        if (obj == null) {
            return new HashMap<>();
        }

        Map<String, Object> resultMap = new HashMap<>();
        Field[] fields = obj.getClass().getDeclaredFields();

        for (Field field : fields) {
            try {
                field.setAccessible(true);
                String fieldName = field.getName();
                Object value = field.get(obj);

                // 自动检测字段名风格并转换
                String convertedFieldName = convertFieldName(fieldName);
                resultMap.put(convertedFieldName, value);

            } catch (IllegalAccessException e) {
                // 忽略无法访问的字段
                System.err.println("无法访问字段: " + field.getName() + ", 错误: " + e.getMessage());
            }
        }

        return resultMap;
    }

    /**
     * 转换字段名，自动检测是驼峰转下划线还是下划线转驼峰
     */
    private static String convertFieldName(String fieldName) {
        if (fieldName == null || fieldName.isEmpty()) {
            return fieldName;
        }

        // 如果包含下划线，则认为是下划线命名转驼峰
        if (fieldName.contains("_")) {
            return snakeToCamel(fieldName);
        }
        // 如果包含大写字母，则认为是驼峰转下划线
        else if (!fieldName.equals(fieldName.toLowerCase())) {
            return camelToSnake(fieldName);
        }
        // 如果全是小写，保持原样
        else {
            return fieldName;
        }
    }

    /**
     * 驼峰转下划线命名
     */
    private static String camelToSnake(String camelCase) {
        if (camelCase == null || camelCase.isEmpty()) {
            return camelCase;
        }

        StringBuilder result = new StringBuilder();
        result.append(Character.toLowerCase(camelCase.charAt(0)));

        for (int i = 1; i < camelCase.length(); i++) {
            char ch = camelCase.charAt(i);
            if (Character.isUpperCase(ch)) {
                result.append('_').append(Character.toLowerCase(ch));
            } else {
                result.append(ch);
            }
        }

        return result.toString();
    }

    /**
     * 下划线转驼峰命名
     */
    private static String snakeToCamel(String snakeCase) {
        if (snakeCase == null || snakeCase.isEmpty()) {
            return snakeCase;
        }

        StringBuilder result = new StringBuilder();
        boolean nextUpper = false;

        for (int i = 0; i < snakeCase.length(); i++) {
            char ch = snakeCase.charAt(i);
            if (ch == '_') {
                nextUpper = true;
            } else {
                if (nextUpper) {
                    result.append(Character.toUpperCase(ch));
                    nextUpper = false;
                } else {
                    result.append(Character.toLowerCase(ch));
                }
            }
        }

        return result.toString();
    }

    // 测试用的示例类
    public static class AmazonTask {
        private String taskName;
        private String taskType;
        private String createUser;

        public AmazonTask(String taskName, String taskType, String createUser) {
            this.taskName = taskName;
            this.taskType = taskType;
            this.createUser = createUser;
        }

        // getters and setters
        public String getTaskName() { return taskName; }
        public void setTaskName(String taskName) { this.taskName = taskName; }
        public String getTaskType() { return taskType; }
        public void setTaskType(String taskType) { this.taskType = taskType; }
        public String getCreateUser() { return createUser; }
        public void setCreateUser(String createUser) { this.createUser = createUser; }
    }

    public static class LoginUser {
        private String userName;
        private String userAge;
        private String loginTime;

        public LoginUser(String userName, String userAge, String loginTime) {
            this.userName = userName;
            this.userAge = userAge;
            this.loginTime = loginTime;
        }

        // getters and setters
        public String getUserName() { return userName; }
        public void setUserName(String userName) { this.userName = userName; }
        public String getUserAge() { return userAge; }
        public void setUserAge(String userAge) { this.userAge = userAge; }
        public String getLoginTime() { return loginTime; }
        public void setLoginTime(String loginTime) { this.loginTime = loginTime; }
    }

    // 测试方法
    public static void main(String[] args) {
        // 测试单体对象
        AmazonTask task = new AmazonTask("testTask", "import", "admin");
        List<Map<String, Object>> result1 = convertToCamelCaseMap(task);
        System.out.println("单体对象转换结果: " + result1);

        // 测试列表对象
        List<AmazonTask> tasks = Arrays.asList(
                new AmazonTask("task1", "type1", "user1"),
                new AmazonTask("task2", "type2", "user2")
        );
        List<Map<String, Object>> result2 = convertToCamelCaseMap(tasks);
        System.out.println("列表对象转换结果: " + result2);

        // 测试下划线转驼峰
        LoginUser user = new LoginUser("john", "25", "2024-01-01");
        List<Map<String, Object>> result3 = convertToCamelCaseMap(user);
        System.out.println("下划线转驼峰结果: " + result3);
    }
}
